import DataManager from "../../Runtime/DataManager"
import { TalentManager } from "../../Runtime/TalentManager"
import { Singleton } from "../Singleton"
import { EntityTypeEnum, SelectPoolTypeEnum, StateTypeEnum } from "../common/Enum"
import { GSelectPool } from "../common/Global"
import { deepClone } from "../common/Util"
import { AttributeManager } from "./AttributeManager"
import { ConfigManager } from "./ConfigManager"
import { GameLogic } from "./GameLogic"
import { SkillManager } from "./SkillManager"

export class SelectManager extends Singleton {

    static get Ins() {
        return super.GetInstance<SelectManager>()
    }

    pool: { id: number, star: number }[] = []

    /** 洗牌 */
    shuffle() {

        const tempPool: [] = deepClone(DataManager.Ins.selectPool)
        this.pool = []
        for (let i = 0; i < 3; i++) {
            const randomIndex = Math.random() * tempPool.length
            const index = Math.floor(randomIndex)
            const poolId = tempPool.splice(index, 1)[0]
            const poolCfg = ConfigManager.Ins.getSelectPoolCfg(poolId)
            if (!poolCfg) continue
            const entityType = poolCfg.entityType
            let entityStar = 1

            for (const weapon of DataManager.Ins.state.weapons) {
                if (entityType === weapon.entityType) {
                    entityStar = weapon.star + 1
                    break
                }
            }
            for (const props of DataManager.Ins.state.props) {
                if (entityType === props.entityType) {
                    entityStar = props.star + 1
                    break
                }
            }

            if (poolCfg.selectType == SelectPoolTypeEnum.skill) {
                entityStar = 5
            }

            const data = {
                id: poolId,
                star: entityStar
            }
            this.pool.push(data)
        }
    }

    /** 做选择 */
    doSelect(arg: 0 | 1 | 2) {
        const { id, star } = SelectManager.Ins.pool[arg]
        const pool = ConfigManager.Ins.getSelectPoolCfg(id)
        const entity = ConfigManager.Ins.getEntityCfg(pool.entityType)
        if (pool.selectType == SelectPoolTypeEnum.weapon) {
            const { entityType } = ConfigManager.Ins.getWeaponCfg({ entityType: pool.entityType, star })
            if (star == 1) {

                DataManager.Ins.state.weapons.push({
                    id: ++DataManager.Ins.state.nextId,
                    owner: DataManager.Ins.myId,
                    entityType: Number(entity.entityType),
                    position: { x: 0, y: 0 },
                    direction: { x: 1, y: 0 },
                    shootCD: 0,
                    searchCD: 0,
                    targetId: 0,
                    state: StateTypeEnum.idle,
                    star,
                })

            } else {
                for (const weapon of DataManager.Ins.state.weapons) {
                    if (weapon.entityType == entityType) {
                        weapon.star = star
                        break
                    }
                }
            }
            GameLogic.Ins.setWeaponPos(DataManager.Ins.state.weapons)
        } else if (pool.selectType == SelectPoolTypeEnum.prop) {
            const { entityType } = ConfigManager.Ins.getPropCfg({ entityType: pool.entityType, star })
            if (star == 1) {
                DataManager.Ins.state.props.push({
                    id: DataManager.Ins.state.nextId,
                    owner: DataManager.Ins.myId,
                    entityType: entity.entityType,
                    star
                })
            } else {
                for (const prop of DataManager.Ins.state.props) {
                    if (prop.entityType == entityType) {
                        prop.star = star
                        break
                    }
                }
            }
        } else if (pool.selectType == SelectPoolTypeEnum.skill) {
            SkillManager.Ins.learnSkill(entity.entityType)
        }
        DataManager.Ins.state.actors[0].skillPoint--
        AttributeManager.Ins.countAttr()
        this.checkWeaponAndPropNumber()
    }

    /** 选择池中删除掉选项 */
    poolDelet(entityType: EntityTypeEnum) {
        for (const i in DataManager.Ins.selectPool) {
            const id = DataManager.Ins.selectPool[i]
            const type = GSelectPool[id].entityType
            if (type == entityType) {
                DataManager.Ins.selectPool.splice(Number(i), 1)
            }
        }
    }

    /** 检测武器和道具数量，满了移除 */
    checkWeaponAndPropNumber() {

        for (const key in DataManager.Ins.state.weapons) {
            const { star, entityType } = DataManager.Ins.state.weapons[key]
            if (star >= 5 + TalentManager.Ins.getWeaponStar()) {
                this.poolDelet(entityType)
            }
        }

        for (const key in DataManager.Ins.state.props) {
            const { star, entityType } = DataManager.Ins.state.props[key]
            if (star >= 5) {
                this.poolDelet(entityType)
            }
        }

        /** 移除武器 */
        if (DataManager.Ins.state.weapons.length >= AttributeManager.Ins.weaponNumber) {
            const tempPool = []
            for (let i = DataManager.Ins.selectPool.length - 1; i >= 0; i--) {
                const id = DataManager.Ins.selectPool[i]
                const poolCfg = ConfigManager.Ins.getSelectPoolCfg(id)
                /** 武器类型 */
                if (poolCfg.selectType == SelectPoolTypeEnum.weapon) {
                    for (const { entityType } of DataManager.Ins.state.weapons) {
                        /** 已拥有的武器 */
                        if (entityType == poolCfg.entityType) {
                            tempPool.push(i)
                            break
                        }
                    }
                }
            }

            for (let i = DataManager.Ins.selectPool.length - 1; i >= 0; i--) {
                const id = DataManager.Ins.selectPool[i]
                const poolCfg = ConfigManager.Ins.getSelectPoolCfg(id)
                if (!tempPool.includes(i) && poolCfg.selectType === SelectPoolTypeEnum.weapon) {
                    DataManager.Ins.selectPool.splice(i, 1)
                }
            }
        }

        /** 移除道具 */
        if (DataManager.Ins.state.props.length >= AttributeManager.Ins.propNumber) {
            const tempPool = []
            for (let i = DataManager.Ins.selectPool.length - 1; i >= 0; i--) {
                const id = DataManager.Ins.selectPool[i]
                const poolCfg = ConfigManager.Ins.getSelectPoolCfg(id)

                /** 道具类型 */
                if (poolCfg.selectType == SelectPoolTypeEnum.prop) {
                    for (const { entityType } of DataManager.Ins.state.props) {
                        /** 已拥有的道具 */
                        if (entityType == poolCfg.entityType) {
                            tempPool.push(i)
                            break
                        }
                    }
                }
            }

            for (let i = DataManager.Ins.selectPool.length - 1; i >= 0; i--) {
                const id = DataManager.Ins.selectPool[i]
                const poolCfg = ConfigManager.Ins.getSelectPoolCfg(id)
                if (!tempPool.includes(i) && poolCfg.selectType === SelectPoolTypeEnum.prop) {
                    DataManager.Ins.selectPool.splice(i, 1)
                }
            }
        }

        /** 移除技能 */
        {
            for (const key in DataManager.Ins.state.skill) {
                const skill = DataManager.Ins.state.skill[key]
                for (let i = DataManager.Ins.selectPool.length - 1; i >= 0; i--) {
                    const id = DataManager.Ins.selectPool[i]
                    const poolCfg = ConfigManager.Ins.getSelectPoolCfg(id)
                    if (poolCfg.entityType === skill.entityType) {
                        DataManager.Ins.selectPool.splice(i, 1)
                    }
                }
            }
        }

    }

    /** 所有选择池子 */
    setSelectPool() {
        DataManager.Ins.selectPool = []
        for (const key in GSelectPool) {
            if (GSelectPool[key].selectType != SelectPoolTypeEnum.skill) {
                if (GSelectPool[key].isUnlock) {
                    DataManager.Ins.selectPool.push(Number(key))
                }
            } else {
                this.setSelectSKillPoolBySn(GSelectPool[key].entityType, Number(key))
            }
        }
        TalentManager.Ins.pushTalentPropPool()
        TalentManager.Ins.pushTalentWeaponPool()
        this.checkWeaponAndPropNumber()
    }

    /** 武器选择池 */
    setSelectWeaponPool() {
        DataManager.Ins.selectPool = []
        for (const key in GSelectPool) {
            if (GSelectPool[key].selectType == SelectPoolTypeEnum.weapon && GSelectPool[key].isUnlock) {
                DataManager.Ins.selectPool.push(Number(key))
            }
        }
        TalentManager.Ins.pushTalentWeaponPool()
        this.checkWeaponAndPropNumber()
    }

    /** 填充技能进入选择池 */
    setSelectSKillPoolBySn(sn: number, key: number) {
        const LOCK = {
            locked: 0,
            unlock: 1,
        }
        const skillCfg = ConfigManager.Ins.getSkillCfg(sn)
        // 是否已解锁
        let isUnlock = LOCK.unlock

        // 拥有指定道具解锁
        if (skillCfg.unlockProp) {
            const maxProp = DataManager.Ins.state.props.find((v) => v.entityType == skillCfg.unlockProp && v.star >= 5)
            if (!maxProp) {
                isUnlock = LOCK.locked
            }
        }

        // 拥有指定武器解锁
        if (skillCfg.unlockWeapon) {

            const lockArr = []
            for (const key in skillCfg.unlockWeapon) {
                lockArr[key] = LOCK.locked
                const weaponType = skillCfg.unlockWeapon[key]
                for (const { entityType } of DataManager.Ins.state.weapons) {
                    if (weaponType == entityType) {
                        lockArr[key] = LOCK.unlock
                    }
                }
            }

            for (const lock of lockArr) {
                if (lock == LOCK.locked) {
                    isUnlock = LOCK.locked
                }
            }
        }

        if (isUnlock == LOCK.unlock) {
            DataManager.Ins.selectPool.push(key)
        }
    }

}